#!/usr/bin/env python

""" CLASS/MODULE:
    Purpose:
"""
__author__ = 'liwei79@gmail.com'

from RTLReg import *

class Operand:
    """ Virtual class """
    def __init__(self):
        assert(0 and "Should not use Operand directly")

class OpndNum(Operand): 
    def __init__(self, opnd):
        assert(isinstance(opnd, int))
        self.num = opnd

    def __repr__(self):
        return repr(self.num)

    def getNum(self):
        return self.num

class OpndReg(Operand):
    def __init__(self, opnd):
        if isinstance(opnd, RTLReg):
            self.reg = opnd
        else:
            self.reg = RTLReg(opnd)

    def __repr__(self):
        return repr(self.reg)

    def getReg(self):
        return self.reg

class OpndSym(Operand):
    def __init__(self, opnd):
        assert(isinstance(opnd, str))
        self.sym = opnd

    def __repr__(self):
        #return "\"" + self.sym + "\""
        return repr(self.sym)

    def getSym(self):
        return self.sym

class OpndStr(Operand):
    def __init__(self, opnd):
        assert(isinstance(opnd, str))
        self.str = opnd

    def __repr__(self):
        return repr(self.str)

    def getStr(self):
        return self.str

class OpndLst(Operand):
    def __init__(self, opnd):
        assert(isinstance(opnd, list))
        self.lst = opnd
        self.checkLstElems()

    def checkLstElems(self):
        for elm in self.lst:
            assert(isinstance(elm, (Operand)))

    def __repr__(self):
        str = "("
        for elm in self.lst:
            #Should not allow recursive list operand
            assert(isinstance(elm, (Operand)))
            str = str + repr(elm)
            if elm != self.lst[-1]:
                str = str + ", "
        return str + ")"

    def appendOpnd(self, opnd):
        self.lst.append(opnd)

    def getLst(self):
        return self.lst

#Self-testing
if __name__ == "__main__":
     o1 = OpndNum(10)
     o2 = OpndReg(RTLReg(10))
     o3 = OpndSym("foo")
     o4 = OpndReg(RTLReg("b"))
     o5 = OpndLst([o1,o2,o3, o4])
     print o5
